// creates a global "addWheelListener" method
// example: addWheelListener( elem, function( e ) { console.log( e.deltaY ); e.preventDefault(); } );
(function (window, document) {
  let prefix = '';
  let _addEventListener;
  let support;

  // detect event model
  if (window.addEventListener) {
    _addEventListener = 'addEventListener';
  } else {
    _addEventListener = 'attachEvent';
    prefix = 'on';
  }

  // detect available wheel event
  if ('onwheel' in document.createElement('div')) {
    support = 'wheel';
  } else if (document.onmousewheel !== undefined) {
    support = 'mousewheel';
  } else {
    support = 'DOMMouseScroll';
  }

  window.addWheelListener = function (elem, callback, useCapture) {
    _addWheelListener(elem, support, callback, useCapture);

    // handle MozMousePixelScroll in older Firefox
    if (support === 'DOMMouseScroll') {
      _addWheelListener(elem, 'MozMousePixelScroll', callback, useCapture);
    }
  };

  function _addWheelListener(elem, eventName, callback, useCapture) {
    elem[_addEventListener](
      prefix + eventName,
      support === 'wheel'
        ? callback
        : function (originalEvent) {
            !originalEvent && (originalEvent = window.event);

            // create a normalized event object
            const event = {
              // keep a ref to the original event object
              originalEvent,
              target: originalEvent.target || originalEvent.srcElement,
              type: 'wheel',
              deltaMode: originalEvent.type === 'MozMousePixelScroll' ? 0 : 1,
              deltaX: 0,
              deltaZ: 0,
              preventDefault() {
                originalEvent.preventDefault ? originalEvent.preventDefault() : (originalEvent.returnValue = false);
              }
            };

            // calculate deltaY (and deltaX) according to the event
            if (support === 'mousewheel') {
              event.deltaY = (-1 / 40) * originalEvent.wheelDelta;
              // Webkit also support wheelDeltaX
              originalEvent.wheelDeltaX && (event.deltaX = (-1 / 40) * originalEvent.wheelDeltaX);
            } else {
              event.deltaY = originalEvent.detail;
            }

            // it's time to fire the callback
            return callback(event);
          },
      useCapture || false
    );
  }
})(window, document);
